/*
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License");  you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * http//www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 *
 * The Original Code is OWLArAPI_ProtegeImpl.
 *
 * The Initial Developer of the Original Code is University of Roma Tor Vergata.
 * Portions created by University of Roma Tor Vergata are Copyright (C) 2009.
 * All Rights Reserved.
 *
 * OWLArAPI_ProtegeImpl was developed by the Artificial Intelligence Research Group
 * (ai-nlp.info.uniroma2.it) at the University of Roma Tor Vergata
 * Current information about OWLArAPI_ProtegeImpl can be obtained at 
 * http//ai-nlp.info.uniroma2.it/software/...
 *
 */

/*
 * Contributor(s): Armando Stellato stellato@info.uniroma2.it
 */
package it.uniroma2.art.owlart.protegeimpl.models;

import it.uniroma2.art.owlart.exceptions.ModelAccessException;
import it.uniroma2.art.owlart.model.ARTResource;
import it.uniroma2.art.owlart.model.ARTURIResource;
import it.uniroma2.art.owlart.models.impl.OWLModelImpl;
import it.uniroma2.art.owlart.models.impl.URIResourceIteratorFilteringResourceIterator;
import it.uniroma2.art.owlart.navigation.ARTLiteralIterator;
import it.uniroma2.art.owlart.navigation.ARTResourceIterator;
import it.uniroma2.art.owlart.navigation.ARTURIResourceIterator;
import it.uniroma2.art.owlart.protegeimpl.Protege2ARTResourceFactory;
import it.uniroma2.art.owlart.protegeimpl.ProtegeARTLiteralIteratorImpl;
import it.uniroma2.art.owlart.protegeimpl.ProtegeARTPropertyIteratorImpl;
import it.uniroma2.art.owlart.protegeimpl.ProtegeARTResourceIteratorImpl;
import it.uniroma2.art.owlart.protegeimpl.ProtegeARTURIResourceIteratorImpl;
import it.uniroma2.art.owlart.vocabulary.OWL;
import it.uniroma2.art.owlart.vocabulary.RDF;
import it.uniroma2.art.owlart.vocabulary.RDFS;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import edu.stanford.smi.protege.model.Project;
import edu.stanford.smi.protegex.owl.model.OWLModel;
import edu.stanford.smi.protegex.owl.model.OWLNamedClass;
import edu.stanford.smi.protegex.owl.model.RDFProperty;
import edu.stanford.smi.protegex.owl.model.RDFResource;
import edu.stanford.smi.protegex.owl.model.triplestore.TripleStore;

public class OWLModelProtegeImpl extends OWLModelImpl {

	protected static Logger logger = LoggerFactory.getLogger(OWLModelProtegeImpl.class);

	TripleStore tripleStore;
	OWLModel owlModel;

	public OWLModelProtegeImpl(BaseRDFModelProtegeImpl baseRep) {
		super(baseRep);
		tripleStore = baseRep.getTripleStore();
		owlModel = baseRep.getProtegeOWLModel();
	}

	public Project getProtegeProject() {
		return ((BaseRDFModelProtegeImpl) baseRep).getProtegeProject();
	}

	public OWLModel getProtegeOWLModel() {
		return ((BaseRDFModelProtegeImpl) baseRep).getProtegeOWLModel();
	}

	public ARTLiteralIterator listValuesOfSubjDTypePropertyPair(ARTResource subject,
			ARTURIResource predicate, boolean inferred, ARTResource... graphs) throws ModelAccessException {
		if (graphs != null && graphs.length != 0)
			throw new IllegalAccessError(BaseRDFModelProtegeImpl.graphUnsupportedMsg);
		/*
		 * Iterator<RDFObject> it = tripleStore.listObjects(
		 * Protege2ARTResourceFactory.aRTResource2ProtegeResource(subject, owlModel),
		 * Protege2ARTResourceFactory.aRTURIResource2ProtegeProperty(predicate, owlModel) ); return new
		 * ProtegeARTLiteralIteratorImpl(it);
		 */
		RDFResource subj = Protege2ARTResourceFactory.aRTResource2ProtegeResource(subject, owlModel);
		RDFProperty prop = Protege2ARTResourceFactory.aRTURIResource2ProtegeProperty(predicate, owlModel);
		return new ProtegeARTLiteralIteratorImpl(subj.getPropertyValueLiterals(prop).iterator());

	}

	public ARTResourceIterator listValuesOfSubjObjTypePropertyPair(ARTResource subject,
			ARTURIResource predicate, boolean inferred, ARTResource... graphs) throws ModelAccessException {
		if (graphs != null && graphs.length != 0)
			throw new IllegalAccessError(BaseRDFModelProtegeImpl.graphUnsupportedMsg);
		/*
		 * Iterator<RDFObject> it = tripleStore.listObjects(
		 * Protege2ARTResourceFactory.aRTResource2ProtegeResource(subject, owlModel),
		 * Protege2ARTResourceFactory.aRTURIResource2ProtegeProperty(predicate, owlModel) ); return new
		 * ProtegeARTLiteralIteratorImpl(it);
		 */
		RDFResource subj = Protege2ARTResourceFactory.aRTResource2ProtegeResource(subject, owlModel);
		RDFProperty prop = Protege2ARTResourceFactory.aRTURIResource2ProtegeProperty(predicate, owlModel);
		return new ProtegeARTResourceIteratorImpl(subj.getPropertyValues(prop).iterator());
	}

	public ARTURIResourceIterator listNamedClasses(boolean inferred, ARTResource... graphs)
			throws ModelAccessException {
		if (graphs != null && graphs.length != 0)
			throw new IllegalAccessError(BaseRDFModelProtegeImpl.graphUnsupportedMsg);

		return new ProtegeARTURIResourceIteratorImpl(owlModel.listOWLNamedClasses());
	}

	public ARTURIResourceIterator listProperties(ARTResource... graphs) throws ModelAccessException {
		if (graphs != null && graphs.length != 0)
			throw new IllegalAccessError(BaseRDFModelProtegeImpl.graphUnsupportedMsg);
		return new ProtegeARTPropertyIteratorImpl(owlModel.listRDFProperties());
	}

	public ARTURIResourceIterator listNamedInstances(ARTResource... graphs) throws ModelAccessException {
		if (graphs != null && graphs.length != 0)
			throw new IllegalAccessError(BaseRDFModelProtegeImpl.graphUnsupportedMsg);
		logger.error("warning this call may vbe not working properly, since not sure all instances will be explicitly instances of owl:thing");

		return new URIResourceIteratorFilteringResourceIterator(listSubjectsOfPredObjPair(RDF.Res.TYPE,
				OWL.Res.THING, true, graphs));
	}

	public ARTLiteralIterator listLabels(ARTResource ontResource, boolean inference, ARTResource... graphs)
			throws ModelAccessException {
		// logger.debug("listing labels");
		return listValuesOfSubjDTypePropertyPair(ontResource, RDFS.Res.LABEL, inference, graphs);
	}

	public ARTResourceIterator listInstances(ARTResource type, boolean inferred, ARTResource... graphs)
			throws ModelAccessException {
		String typeInternalName = owlModel.getResourceNameForURI(((ARTURIResource) type).getURI());
		logger.debug("typeInternalName: " + typeInternalName);
		OWLNamedClass typeCls = owlModel.getOWLNamedClass(typeInternalName);
		System.out.println("URI OF CNOUN" + typeCls.getURI());

		logger.debug("typeCls: " + typeCls);
		return new ProtegeARTResourceIteratorImpl(typeCls.getInstances(inferred).iterator());
	}

	public ARTResourceIterator listSubClasses(ARTResource cls, boolean inferred, ARTResource... graphs)
			throws ModelAccessException {
		String typeInternalName = owlModel.getResourceNameForURI(((ARTURIResource) cls).getURI());
		logger.debug("clsInternalName: " + typeInternalName);
		OWLNamedClass typeCls = owlModel.getOWLNamedClass(typeInternalName);
		System.out.println("URI OF CNOUN" + typeCls.getURI());

		logger.debug("typeCls: " + typeCls);
		return new ProtegeARTResourceIteratorImpl(typeCls.getSubclasses(inferred).iterator());
	}

	public ARTResourceIterator listTypes(ARTResource inst, boolean inferred, ARTResource... graphs)
			throws ModelAccessException {
		String instInternalName = owlModel.getResourceNameForURI(((ARTURIResource) inst).getURI());
		logger.debug("instInternalName: " + instInternalName);
		return listValuesOfSubjObjTypePropertyPair(inst, RDF.Res.TYPE, inferred, graphs);
	}

}
